package com.scalar.chiptrack.adaptor.ikanos.utl;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.InventoryLot;
import com.scalar.chiptrack.adaptor.AssemblyLot;
import com.scalar.chiptrack.adaptor.ShippedLot;
import com.scalar.chiptrack.adaptor.dao.AssemblyAdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.InventoryLotDAO;
import com.scalar.chiptrack.adaptor.dao.ShippedLotDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.ScalarException;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Date;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;


/**
 * Created by IntelliJ IDEA.
 * User: Munugoti
 * Date: Sep 26, 2008
 * Time: 2:24:58 PM
 * To change this template use File | Settings | File Templates.
 */
public class UTLDataParser extends JobHandler implements AdaptorConstants
{
    private static Logger m_parserLogger    = null;
    private String m_dataOutputDir          = null;

    private HashMap m_assyWipDataMap        = new HashMap();
    private HashMap m_assyShipDataMap       = new HashMap();
    private HashMap m_dieBankDataMap        = new HashMap();

    public UTLDataParser() throws ScalarException
    {
        try
        {
            m_dataOutputDir = AdaptorUtils.getDataOutputDir( VENDOR_NAME_UTL, WIP_TYPE_ASSEMBLY );
            AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );
            m_parserLogger = AdaptorUtils.getDataParserLogger( m_dataOutputDir,VENDOR_NAME_UTL );
            AssemblyAdaptorDAO.setLogger( m_parserLogger );   // All the DAOs and Parser should be logging into same file
            InventoryLotDAO.setLogger( m_parserLogger );
            ShippedLotDAO.setLogger( m_parserLogger );
            AdaptorUtils.setLogger( m_parserLogger );
        }
        catch (ScalarException se)
        {
            log("ERROR!! ERROR!! ERROR!! Exception while loading/creating UTL output directory from database, Exception: " + se);
            throw se;
        }
    }
    /**
     *
     * @param args
     * @throws Exception
     */
    public static void main( String args[] ) throws Exception
    {
        try
        {
            new UTLDataParser().execute();
        }
        catch (Exception e)
        {
            throw e;
        }
    }
    //Execute Method
   public void execute() throws Exception
   {
       AdaptorUtils.printHeader(VENDOR_NAME_UTL, CONSTANT_PARSER );

       File doneDestDir = new File( m_dataOutputDir + "/done" );

       File wipDataoutDir = new File( m_dataOutputDir );

       File[] fileList = wipDataoutDir.listFiles();

       if ( ( fileList == null ) || ( fileList.length <= 3 ) )
       {
           log( "No file found in directory: " + wipDataoutDir );
           throw new ScalarException( "No file found in directory: " + wipDataoutDir + "----\n\n" );
       }

       DBTransaction dbTransaction = null;
       ArrayList successFileList   = new ArrayList();
       boolean success             = false;

       try
       {
           for ( int i = 0; i < fileList.length; i++ )
           {
               if ( fileList[i].isDirectory() == true )
               {
                   continue;
               }

               if ( ( fileList[i].getName() != null ) && ( fileList[i].getName().trim().indexOf( UTLPOP3Adaptor.FILE_NAME_DAILY_WIP ) != -1 ) )
               {
                    ArrayList wipLotsList = parseDailyWipReport( fileList[i].getAbsolutePath() );

                    getAllWipLotDetails( wipLotsList );

                    successFileList.add( fileList[i] );
                    success = true;
               }
           }
       }
       catch ( Exception e )
       {
           success = false;
           log( "ERROR!! ERROR!! ERROR!! While parsing and storing File " + e );
           e.printStackTrace();
           throw e;
       }

       // to save the Die Bank lot tables
       try
       {
           if ( m_dieBankDataMap.isEmpty() == false )
           {
               log(" Updating Die Bank Lot Information");
               InventoryLotDAO.saveInventoryLot( dbTransaction/*null*/, m_dieBankDataMap.values().iterator(), INVENTORY_TYPE_DIE_BANK, VENDOR_NAME_UTL );
               success = true;
           }
           else
           {
               InventoryLotDAO.closeInventoryLot(dbTransaction/*null*/, INVENTORY_TYPE_DIE_BANK, VENDOR_NAME_UTL  );
           }
      }
      catch (ScalarException se)
      {
          success = false;
          se.printStackTrace();
          log("ERROR!! ERROR!! ERROR!! Could not update Die Bank Lot information into database: " + se);
          throw se;
      }

       // to save the Assembly lot tables
       try
       {
           if ( m_assyWipDataMap.isEmpty() == false )
           {
               log(" Updating Assembly Lot Information");
               AssemblyAdaptorDAO.saveAssemblyLot( dbTransaction/*null*/, m_assyWipDataMap.values().iterator(), WIP_TYPE_ASSEMBLY, VENDOR_NAME_UTL );
               success = true;
           }
           else
           {
               AssemblyAdaptorDAO.closeAssemblyLot(dbTransaction, WIP_TYPE_ASSEMBLY, VENDOR_NAME_UTL );
           }
      }
      catch (ScalarException se)
      {
          success = false;
          se.printStackTrace();
          log("ERROR!! ERROR!! ERROR!! Could not update Assembly Lot information into database: " + se);
          throw se;
      }

      try
      {
           // Save Assembly Ship Information
           if ( m_assyShipDataMap.isEmpty() == false )
           {
               log( " Updating Assembly Shiping Lot Information" );
               ShippedLotDAO.saveShippedLot( null, m_assyShipDataMap.values().iterator() );
           }
           success = true;
           m_assyShipDataMap.clear();
           m_assyShipDataMap = null;
      }
      catch (ScalarException se)
      {
           success = false;
           se.printStackTrace();
           log( "ERROR!! ERROR!! ERROR!! Could not update Assembly Shipping Lot information into database: " + se );
           throw se;
      }

      // To Close the Drop Out Lots
      AdaptorDAO.closeDropOutLots( VENDOR_NAME_UTL );

      // TO SEND THE NEW LOTS, NEW TRANSIT LOTS, NO PO LOTS, DISCREPANCY LOTS NOTIFICATIONS TO THE USER
      AdaptorDAO.sendAllNotifications( VENDOR_NAME_UTL, true, true, true );

      int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( UTLPOP3Adaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);

      // Update Adaptor_Run_Info table
      try
      {
            if ( success == true )
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, UTLPOP3Adaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
            }
      }
      catch ( ScalarException se )
      {
            success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, UTLPOP3Adaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
            throw se;
       }
        // Move the successful files to 'done' directory
       if ( success )
       {
           AdaptorUtils.moveFilesToDone( successFileList, doneDestDir );
       }
   }//end of execute method


    private ArrayList parseDailyWipReport( String fileName ) throws Exception
    {
        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ArrayList wipLotsList              = new ArrayList();
        String line                     = null;

        try
        {
            File detailWipFile = new File( fileName );
            if ( detailWipFile.exists() == false )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            log("\nFound " + fileName);
            log("Parsing the file for UTL WIP Status Report...");
            System.out.println("\nFound " + fileName);
            System.out.println("Parsing the file for UTL WIP Status Report...");

            BufferedReader reader = new BufferedReader( new FileReader( detailWipFile ) );
            reader.readLine();  // Read out <Report Name> Line
            reader.readLine();  // Read out <Report Date> Line
            reader.readLine();  // Read out <Report header> Line
            while ( ( line = reader.readLine() ) != null )
            {
                UTLWipStatus wipStatus = new UTLWipStatus();

                line = line.replaceAll( "\"", "" );
                //System.out.println("line = " + line);
                String[] token = line.split( "," );

                for (int x = 0; x < token.length; x++)
                {
                    if (token[x] != null && token[x].trim().length() > 0)
                    {
                        switch (x)
                        {
                            case 0:
                                    wipStatus.setCustDevice(token[x].trim() );
                                    break;
                            //case 1: Part ID not Required

                            case 2:
                                    wipStatus.setCustLotId( token[x].trim() );
                                    break;
                            case 3:
                                    wipStatus.setPkgType( token[x].trim() );
                                    break;
                            case 4:
                                    wipStatus.setDateCode( token[x].trim());
                                    break;
                            case 5:
                                    wipStatus.setReceiveQty( token[x].trim());
                                    break;
                            case 6:
                                   wipStatus.setReceiveDate( token[x].trim() );
                                    break;
                            case 7:
                                    wipStatus.setStartDate( token[x].trim() );
                                    break;
                            case 8:
                                    wipStatus.setLotNumber( token[x].trim() );
                                    break;
                            case 9:
                                    wipStatus.setProArea ( token[x].trim() );
                                    break;
                            case 10:
                                    wipStatus.setStage( token[x].trim() );
                                    break;
                            case 11:
                                    wipStatus.setState( token[x].trim() );
                                    break;
                            case 12:
                                    wipStatus.setCurrQtyIn( token[x].trim() );
                                    break;
                            case 13:
                                    wipStatus.setExpectedDate( token[x].trim() );
                                    break;
                            case 14:
                                    wipStatus.setCommitedDate( token[x].trim());
                                    break;
                            //Remaing Fileds Not Required
                         }
                    }
                }
                if (wipStatus.getCustDevice() != null && wipStatus.getCustDevice().length() > 0
                       && wipStatus.getCustLotId() != null && wipStatus.getCustLotId().length() > 0 )
				{
                    wipLotsList.add( wipStatus );
                }
            }

            try
            {
                if ( reader != null )
                {
                   reader.close();
                }
            }
            catch(IOException ignore)
            {

            }

        }
        catch ( Exception ex )
        {   System.out.println("ERROR!!!ERROR!!! While Parsing the UTL Daily WIP Sheet");
            ex.printStackTrace();
            throw ex;
        }

        return wipLotsList;

    } // end of prase Daily WIP method

    private void getAllWipLotDetails(ArrayList allWipList) throws Exception
    {
        UTLWipStatus wipStatus = null;
        InventoryLot inventoryLot   = null;
        AssemblyLot assemblyLot     = null;
        ShippedLot shippedLot       = null;
        String partNumber           = null;
        String lotNumber            = null;
        String fabLotNumber         = null;
        String lotStatus            = null;

        if ( allWipList == null || allWipList.size() <= 0 )
        {
            System.out.println(" No WIP data found");
            return;
        }

        try
        {
            Iterator iterator = allWipList.iterator();

            while (iterator.hasNext())
            {
                wipStatus = (UTLWipStatus) iterator.next();

                fabLotNumber = wipStatus.getCustLotId();
                partNumber = wipStatus.getCustDevice();
                lotNumber  = wipStatus.getLotNumber();

                if ( lotNumber == null )
                {
                    lotNumber = fabLotNumber;
                }
                if( wipStatus.getState() != null && ( "WAIT".equalsIgnoreCase( wipStatus.getState())
                        || "HELD".equalsIgnoreCase( wipStatus.getState()) || wipStatus.getState().indexOf("HLD") != -1 ) )
                {
                    lotStatus = LOT_STATUS_HOLD;
                }
                else
                {
                    lotStatus = LOT_STATUS_RUNNING;
                }

                if ( lotNumber != null && lotNumber.trim().length() > 0 && partNumber != null && partNumber.trim().length() > 0)
                {
                    //DIE BANK LOTS
                    if ( wipStatus.getProArea() != null && "DBANK".equalsIgnoreCase( wipStatus.getProArea() ) )
                    {
                        log("In Die Bank " + lotNumber );

                        if ( partNumber.endsWith("-00") )
                        {
                            partNumber = partNumber.substring(0, partNumber.lastIndexOf("-00") );
                        }

                        inventoryLot = (InventoryLot) m_dieBankDataMap.get( partNumber + fabLotNumber );
                        if ( inventoryLot == null )
                        {
                            inventoryLot = new InventoryLot(VENDOR_NAME_UTL, LOCATION_TYPE_DIE_BANK );
                            m_dieBankDataMap.put( partNumber + fabLotNumber, inventoryLot );
                        }
                        int quantity = 0;
                        if (inventoryLot.getQtyIn() != null)
                        {
                            try
                            {
                                quantity = Integer.parseInt(inventoryLot.getQtyIn());
                            }
                            catch (NumberFormatException ignore) {
                            }
                            try
                            {
                                quantity += Integer.parseInt(wipStatus.getCurrQtyIn() );
                            }
                            catch (NumberFormatException nfe) {
                            }
                        }
                        else
                        {
                            try
                            {
                                quantity = Integer.parseInt( wipStatus.getCurrQtyIn() );
                            }
                            catch (NumberFormatException ignore) {
                            }
                        }

                        if ( quantity > 0 )
                        {
                            inventoryLot.setLotNumber( fabLotNumber );
                            inventoryLot.setPartNumber( partNumber );
                            inventoryLot.setStatus( lotStatus );
                            inventoryLot.setFabLotNumber( fabLotNumber );
                            inventoryLot.setCategory( LOT_CATEGORY_TYPE_PROD );
                            inventoryLot.setQtyIn( quantity +"" );
                            if ( wipStatus.getReceiveDate() != null )
                            {
                                //inventoryLot.setDateIn(StringUtils.formatDate(wipStatus.getReceiveDate(), "dd/MM/yyyy HH:mm:ss", "MM/dd/yyyy HH:mm:ss" ) );
                                inventoryLot.setDateIn(wipStatus.getReceiveDate() );
                            }
                        }
                    }

                    //ASSEMBLY
                    if( wipStatus.getProArea() != null && !"DBANK".equalsIgnoreCase( wipStatus.getProArea() )  && !"SHIP".equalsIgnoreCase( wipStatus.getProArea() )  )
                    {
                        log( "In Assembly " + lotNumber ) ;

                        assemblyLot = (AssemblyLot) m_assyWipDataMap.get( partNumber + lotNumber + fabLotNumber );
                        if (assemblyLot == null)
                        {
                            assemblyLot = new AssemblyLot( VENDOR_NAME_UTL );
                            m_assyWipDataMap.put( partNumber + lotNumber + fabLotNumber, assemblyLot);
                        }

                        int quantity = 0;
                        if (assemblyLot.getQtyIn() != null)
                        {
                            try
                            {
                                quantity = Integer.parseInt(assemblyLot.getQtyIn());
                            }
                            catch (NumberFormatException ignore) {
                            }
                            try
                            {
                                quantity += Integer.parseInt(wipStatus.getCurrQtyIn());
                            }
                            catch (NumberFormatException nfe) {
                            }
                        }
                        else
                        {
                            try
                            {
                                quantity = Integer.parseInt(wipStatus.getCurrQtyIn());
                            }
                            catch (NumberFormatException ignore) {
                            }
                        }
                        if ( quantity > 0 )
                        {
                            assemblyLot.setDeviceName(partNumber);
                            assemblyLot.setLotNumber(lotNumber);
                            assemblyLot.setQtyIn(quantity + "");
                            if ( wipStatus.getStartDate() != null )
                            {
                                //assemblyLot.setDateIn(StringUtils.formatDate(wipStatus.getStartDate(), "dd/MM/yyyy HH:mm:ss", "MM/dd/yyyy HH:mm:ss" ));
                                assemblyLot.setDateIn(wipStatus.getStartDate());
                            }
                            else if ( wipStatus.getReceiveDate() != null )
                            {
                                //assemblyLot.setDateIn(StringUtils.formatDate(wipStatus.getReceiveDate(), "dd/MM/yyyy HH:mm:ss", "MM/dd/yyyy HH:mm:ss" ));
                                assemblyLot.setDateIn(wipStatus.getReceiveDate());

                            }

                            assemblyLot.setFabLotNumber(fabLotNumber);
                            assemblyLot.setStatus(lotStatus );
                            assemblyLot.setCategory(LOT_CATEGORY_TYPE_PROD);
                            assemblyLot.setStage( wipStatus.getStage() );
                            assemblyLot.setDateCode( wipStatus.getDateCode() );

                            if ( wipStatus.getExpectedDate() != null && wipStatus.getExpectedDate().length() > 8 )
                            {
                                 assemblyLot.setExpectedDateOut( wipStatus.getExpectedDate());
                            }
                        }
                    }

                    if( wipStatus.getProArea() != null && "SHIP".equalsIgnoreCase( wipStatus.getProArea() )  )
                    {
                        log("In Assembly Ship" + lotNumber);
                        shippedLot = (ShippedLot) m_assyShipDataMap.get ( partNumber + fabLotNumber + lotNumber + wipStatus.getCommitedDate() );

                        if ( shippedLot == null )
                        {
                            shippedLot = new ShippedLot(VENDOR_NAME_UTL, LOCATION_TYPE_ASSEMBLY);
                            m_assyShipDataMap.put( partNumber + fabLotNumber + lotNumber + wipStatus.getCommitedDate(), shippedLot );
                        }

                        int quantity = 0;
                        if ( shippedLot.getShipQty() != null )
                        {
                            try
                            {
                                quantity = Integer.parseInt( shippedLot.getShipQty() );
                            }
                            catch ( NumberFormatException ignore )
                            {
                                quantity = 0;
                            }
                            try
                            {
                                quantity += Integer.parseInt( wipStatus.getCurrQtyIn() );
                            }
                            catch ( NumberFormatException ignore )
                            {
                                quantity = 0;
                            }
                        }
                        else
                        {
                            try
                            {
                                quantity = Integer.parseInt( wipStatus.getCurrQtyIn() );
                            }
                            catch ( NumberFormatException ignore )
                            {
                                quantity = 0;
                            }
                        }

                        if ( quantity > 0 )
                        {
                            shippedLot.setLotNumber( lotNumber );
                            shippedLot.setPartNumber( partNumber );
                            shippedLot.setShipDate( wipStatus.getCommitedDate() );
                            shippedLot.setShipQty( quantity + "" );
                            shippedLot.setFabLotNumber( fabLotNumber );
                            shippedLot.setProcessType( LOCATION_TYPE_ASSEMBLY );
                            shippedLot.setPackageType( wipStatus.getPkgType() );
                        }
                    }
                }
            }
        }
        catch( Exception e)
        {
            System.out.println("ERROR!! ERROR!! While parsing the UTL Assy Wip Data Details........" + e );
            e.printStackTrace();
            throw e;
        }
    }

    private static void log( String message )
    {

        if ( message == null ) return;

        if ( m_parserLogger != null )
        {
            synchronized ( m_parserLogger )
            {
                m_parserLogger.logDebug( message + LINE_SEPARATOR );
            }
        }
        else
        {
            System.out.println( message );
        }
    }
}

